/// 映射（Map）
/// 映射也就是键值对，每个键都有与之相关联的一个值

/// 几种构造函数
void createMap () {
  var map = <String, int>{'a':1, 'b':2, 'c':3};
  print(map['a']);
}

/// Map.fromIterable(Iterable iterable, {K key(element), V value(element)})
void createMap2 () {
  var list = <int>[1, 2, 3];

  // 以下代码用到了速写语法，后面会详细讲解
  Map<String, int> map1 = Map.fromIterable(list,
     key: (item) => item.toString(),
     value: (item) => item * item
  );

  print(map1['1'] + map1['2']);
  // -> 1 + 4 = 5

  print(map1['3'] - map1['2']);
  // -> 9 - 4 = 5

  // 速写语法2
  var map2 = { for (var item in list) item.toString() : item * item };
  // -> [1, 4, 9]

  print(map2['1'] + map2['2']);
  // -> 1 + 4 = 5

  print(map2['3'] - map2['2']);
  // -> 9 - 4 = 5
}

/// Map.fromIterables(Iterable keys, Iterable values)
void createMap3 () {
  // List<String> letters = ['b', 'c'];
  var letters = <String>['b', 'c'];
  // List<String> words = ['bad', 'cat'];
  var words = <String>['bad', 'cat'];
  // Map<String, String> map = new Map.fromIterables(letters, words);
  var map = Map<String, String>.fromIterables(letters, words);
  // -> {b: bad, c: cat}

  var string = map['b'] + map['c'];
  // -> badcat
}

/// 所有属性
void createMap4 () {
  var map = <String, int>{ 'a': 1, 'b': 2, 'c': 3 };
  // 返回映射的哈希码
  print(map.hashCode);
  // -> 185181462

  // 映射上是否没有键值对
  print(map.isEmpty);
  // -> false

  // 映射上是否有键值对
  print(map.isNotEmpty);
  // -> true

  // 返回映射的所有键
  print(map.keys);
  // -> (a, b, c)

  // 返回映射的所有值
  print(map.values);
  // -> (1, 2, 3)

  // 返回映射上键值对的数目
  print(map.length);
  // -> 3

  // 返回对象运行时的类型
  print(map.runtimeType);
  // -> IdentityMap<String, int>
}

/// 常用方法
void createMap5 () {
  var map = <String, int>{ 'a': 1, 'b': 2, 'c': 3 };
  // 返回映射的字符串表示
  print(map.toString());
  // -> {a: 1, b: 2, c: 3}
  // 按顺序迭代映射
  map.forEach((key, value){
    print(key + ' : ' + value.toString());
    // -> a : 1
    // -> b : 2
    // -> c : 3
  });
  // 添加其他键值对到映射中
  map.addAll({'d':4, 'e':5});
  // -> {a: 1, b: 2, c: 3, d: 4, e: 5}
  // 映射是否包含指定键
  print(map.containsKey('d'));
  // -> true
  // 映射是否包含指定值
  print(map.containsValue(5));
  // -> true
  // 删除指定键值对
  map.remove('a');
  // -> {b: 2, c: 3, d: 4, e: 5}
  // 删除所有键值对
  map.clear();
  // -> {}

  var scores = <String, int>{'Bob': 36};
  for (var key in ['Bob', 'Rohan', 'Sophena']) {
    // 查找指定键，如果不存在就添加
    scores.putIfAbsent(key, () => key.length);
  }
  print(scores['Bob']);
  // -> 36
  print(scores['Rohan']);
  // -> 5
  print(scores['Sophena']);
  // -> 7
}
void main () {
  createMap();
  createMap2();
  createMap3();
  createMap4();
  createMap5();
}
